Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRT constraints and AMM benchmarks #4750

Closed

Conversation

ignazio-bovo
Copy link
Contributor

@ignazio-bovo ignazio-bovo commented May 5, 2023

fixes:

  • max yearly patronage rate
  • patronage rate computation & approximation updated
  • patronage tests refactored & updated
  • add max limit for transfers
  • adds benchmarks for amm (as Amm benchmark #4481 has lost all changes)

Resources and References:

@vercel
Copy link

vercel bot commented May 5, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Updated (UTC)
pioneer-testnet ⬜️ Ignored (Inspect) May 19, 2023 0:15am

@ignazio-bovo ignazio-bovo changed the title Nara crt constraints Nara crt constraints and AMM benchmarks May 5, 2023
runtime-modules/project-token/src/lib.rs Show resolved Hide resolved
runtime-modules/project-token/src/lib.rs Outdated Show resolved Hide resolved
@@ -913,10 +912,10 @@ decl_module! {
/// - total supply decreased by amount
/// - respective JOY amount transferred from amm treasury account to user account
/// - event deposited
#[weight = 100_000_000] // TODO: adjust weight
fn sell_on_amm(origin, token_id: T::TokenId, member_id: T::MemberId, amount: <T as Config>::Balance, deadline: Option<<T as timestamp::Config>::Moment>, slippage_tolerance: Option<(Permill, JoyBalanceOf<T>)>) -> DispatchResult {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, timestamp info can be manipulated by validator node (https://neptunemutual.com/blog/understanding-block-timestamp-manipulation/)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like the deadline was used for any purpose anyway, so it makes sense to drop it.

runtime-modules/project-token/src/lib.rs Outdated Show resolved Hide resolved
runtime-modules/project-token/src/tests/patronage.rs Outdated Show resolved Hide resolved
runtime-modules/project-token/src/tests/patronage.rs Outdated Show resolved Hide resolved
runtime-modules/project-token/src/tests/patronage.rs Outdated Show resolved Hide resolved
@@ -886,6 +886,7 @@ parameter_types! {
pub const ProjectTokenModuleId: PalletId = PalletId(*b"mo:token"); // module: token
pub const MaxVestingSchedulesPerAccountPerToken: u32 = 5;
pub const BlocksPerYear: u32 = 5259600; // 365,25 * 24 * 60 * 60 / 6
pub const MaxOutputs: u32 = 256; // TODO(Martin, Ignazio) : find a suitable value
Copy link
Contributor Author

@ignazio-bovo ignazio-bovo May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a separate issue for:

  • max patronage rate
  • min amm slope

runtime-modules/project-token/src/types.rs Outdated Show resolved Hide resolved
ignazio-bovo

This comment was marked as outdated.

@@ -11,6 +11,8 @@ pub fn production_config() -> ProjectTokenConfig {
min_revenue_split_duration: days!(21),
min_revenue_split_time_to_start: 0,
sale_platform_fee: Permill::from_percent(2),
max_yearly_patronage_rate: Permill::from_percent(5).into(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no migration is needed for these parameters as they are new with V2002

Copy link
Contributor Author

@ignazio-bovo ignazio-bovo May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok it appears no (data) migrations are needed here on content pallet

let config = GenesisConfigBuilder::new_empty()
.with_token_and_owner(token_id, params.build(), owner_id, supply)
.build();
fn claim_patronage_ok_with_correct_credit_accounting_and_more_than_100_percent_supply() {
Copy link
Contributor Author

@ignazio-bovo ignazio-bovo May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also accounts for testing numeric precision, however there are several tests in the common/numerical.rs library for this

const [proposalId, generalProposalParameters, runtimeProposalDetails, proposalThreadId] =
new ProposalCreatedEvent_V1001(event).params
specVersion >= 2002 ? new ProposalCreatedEvent_V2002(event).params : new ProposalCreatedEvent_V1001(event).params
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the mappings in order to account for the new update max yearly patronage rate proposal?
If so I need to open an issue about this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it depends on when we decide to enable creating tokens, or start adding integration tests then yes we would need to update the mappings starting with handling new proposal type in parseProposalDetails()

Copy link
Member

@mnaamani mnaamani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left just an initial high level review, did not go into implementation details yet.

@@ -11,6 +11,9 @@ pub fn production_config() -> ProjectTokenConfig {
min_revenue_split_duration: days!(21),
min_revenue_split_time_to_start: 0,
sale_platform_fee: Permill::from_percent(2),
max_yearly_patronage_rate: Permill::from_percent(20).into(), // TODO: update, raising might make benchmarks fail
min_amm_slope_parameter: 10, // TODO: update, raising might make benchmarks fail
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default storage value set in project-token decl_storage macro is 15% for max_yearly_patronage_rate and 0 for min_amm_slope_parameter. In a runtime upgrade those defaults will be used because they are now being introduced in nara upgrade. If we are not happy with the defaults, we need to add a migration on_runtime_upgrade.

const [proposalId, generalProposalParameters, runtimeProposalDetails, proposalThreadId] =
new ProposalCreatedEvent_V1001(event).params
specVersion >= 2002 ? new ProposalCreatedEvent_V2002(event).params : new ProposalCreatedEvent_V1001(event).params
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it depends on when we decide to enable creating tokens, or start adding integration tests then yes we would need to update the mappings starting with handling new proposal type in parseProposalDetails()

FixedPointNumber, FixedU128, PerThing, Permill, Perquintill,
};

pub const ORDER: usize = 20;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you comment what this constant stands for?

pub(crate) fn update_max_yearly_patronage_rate_proposal() -> ProposalParameters<BlockNumber, Balance>
{
ProposalParameters {
voting_period: days!(7),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

voting and grace periods for testing,playground need to be much lower. See values for other proposals.

@@ -16,23 +16,22 @@
// limitations under the License.

//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2022-10-20 (Y/M/D)
//! DATE: 2023-05-11 (Y/M/D)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block, extrinsics and rocksdb _weights.rs should not be modified in this PR.

// Storage: Token TokenInfoById (r:1 w:1)
// Storage: Token MinAmmSlopeParameter (r:1 w:0)
// Storage: System Account (r:1 w:1)
fn activate_amm() -> Weight {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we can keep only the new weight functions (and maybe issue_new_token which was modified) in this file and checkout all other changes.
We will do a final weight generation step before nara release.

@@ -913,10 +912,10 @@ decl_module! {
/// - total supply decreased by amount
/// - respective JOY amount transferred from amm treasury account to user account
/// - event deposited
#[weight = 100_000_000] // TODO: adjust weight
fn sell_on_amm(origin, token_id: T::TokenId, member_id: T::MemberId, amount: <T as Config>::Balance, deadline: Option<<T as timestamp::Config>::Moment>, slippage_tolerance: Option<(Permill, JoyBalanceOf<T>)>) -> DispatchResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like the deadline was used for any purpose anyway, so it makes sense to drop it.

@@ -79,15 +79,15 @@ const MAX_KILOBYTES_METADATA: u32 = 100;

// Creator tokens
const MAX_CRT_INITIAL_ALLOCATION_MEMBERS: u32 = 1024;
const MAX_CRT_ISSUER_TRANSFER_OUTPUTS: u32 = 1024;
const MAX_CRT_ISSUER_TRANSFER_OUTPUTS: u32 = 256; // same as in Token MaxOuputs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is a runtime constant, perhaps it can be read from the pallet instead of re-defining a separate constant and having to remember to keep them in sync?

@mnaamani mnaamani self-requested a review May 16, 2023 09:30
pub const ORDER: usize = 20;

// does not work with 100% interest
pub fn natural_log_1_plus_x(interest: Permill) -> Perquintill {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this is not used expect internally from one_plus_interest_pow_frac so maybe keep it private?
Similarly for one_plus_interest_pow_frac.

If this function "does not work with 100% interest" would would the output be, and should we guard against invalid input?

result
}

pub fn one_plus_interest_pow_frac(interest: Permill, exp: Perquintill) -> FixedU128 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add rust-doc just to show what is being calculated

runtime-modules/project-token/src/benchmarking.rs Outdated Show resolved Hide resolved

// Patronage
const DEFAULT_PATRONAGE: YearlyRate = YearlyRate(Permill::from_percent(1));
const DEFAULT_SPLIT_ALLOCATION: u32 = 4_000_000; // DEFAULT_REVENUE_SPLIT_RATE * DEFAULT_SPLIT_REVENUE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not evaluate it as per commentDEFAULT_REVENUE_SPLIT_RATE * DEFAULT_SPLIT_REVENUE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because DEFAULT_PATRONAGE: Permill and the multiplaction is a non constant operation, so rustc will throw error

})
.collect()
);
let mut outputs = TransferOutputsOf::<T>::with_bounded_capacity((o + 1) as usize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by adding + 1 are not going over the MAX_TX_OUTPUTS. range of o starts at 1, so I don't see the need to add +1 if we are concerned calling with_bounded_capacity with args 0..

let approx =
Token::account_info_by_token_and_member(DEFAULT_TOKEN_ID, DEFAULT_ISSUER_MEMBER_ID)
.transferrable::<Test>(System::block_number());
let target = 1000000181215750585898368181876;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a hard time accepting these pre-computed values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

vec::Vec,
};
use storage::{BagId, DataObjectCreationParameters};

// crate imports
use crate::{errors::Error, Config, RepayableBloatBondOf};

// trait "aliases"
// `BlockNumber` will be implemented as `u64` in the runtime configuration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The runtime implements BlockNumber as u32, not u64. Is this assumption here problematic?

Copy link
Contributor Author

@ignazio-bovo ignazio-bovo May 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it should not. According to the trait

Self {
slope: params.slope,
intercept: params.intercept,
provided_supply: Balance::zero(),
}
}
pub(crate) fn eval<T: Config>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed like a better place for the 'eval' implementation., but it was made into a standalone function in the content pallet. What is the reason behind this?

impl Add for YearlyRate {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.add(rhs.0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we be concerned with overflows?

@@ -148,7 +148,7 @@ macro_rules! hours {
#[macro_export]
macro_rules! days {
($a:expr) => {{
hours!(24) * $a
((24 * 60 * 60 * 1000) / ExpectedBlockTime::get()) as u32 * $a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mathematically it looks the same to me, is this implementation more accurate (due to integer maths?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was in order to silence clippy, I will revisit

@bedeho bedeho changed the title Nara crt constraints and AMM benchmarks CRT constraints and AMM benchmarks Sep 13, 2023
@bedeho bedeho added crt_release_placeholder Placeholder to whatever release has CRT and removed crt-v1 labels Sep 13, 2023
@mnaamani
Copy link
Member

@ignazio-bovo should we close this PR, it was merged into nara if I'm not mistaken?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crt_release_placeholder Placeholder to whatever release has CRT project_token Project tokens runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants